﻿using DevelopAssistant.Common;
using DevelopAssistant.Core.DBMS;
using DevelopAssistant.Service;
using DevelopAssistant.Service.TemplatingEngine;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace DevelopAssistant.Core.ToolBox
{
    public partial class CreateCodePicker : ToolBoxBase
    {
        MainForm mainform;
        DataBaseServer server;

        TextTemplatingEngine host = new TextTemplatingEngine(); 

        public string TableName { get; set; }

        public CreateCodePicker()
        {
            InitializeComponent();
            InitializeControls();
        }

        public CreateCodePicker(string text, string code)
            : this()
        {
            TableName = text;
            this.txtTableName.Text = TableName;
        }

        private void InitializeControls()
        {
            this.panel1.TopBlackColor = Color.WhiteSmoke;
            this.panel1.BottomBlackColor = SystemColors.Control;

            ListItem item = null;
            item = new ListItem();
            item.Text = "DbTypes.Sql";
            item.Value = "Sql";
            combTypes.Items.Add(item);
            item = new ListItem();
            item.Text = "DbTypes.Oracle";
            item.Value = "Oracle";
            combTypes.Items.Add(item);
            item = new ListItem();
            item.Text = "DbTypes.MySql";
            item.Value = "MySql";
            combTypes.Items.Add(item);
            item = new ListItem();
            item.Text = "DbTypes.OleDb";
            item.Value = "OleDb";
            combTypes.Items.Add(item);
            item = new ListItem();
            item.Text = "DbTypes.SqlLite";
            item.Value = "SqlLite";
            combTypes.Items.Add(item);

            combTypes.SelectedIndex = 0;

            lblStateMsg.Text = "";

        }
        
        private void btnApplyOk_Click(object sender, EventArgs e)
        {
            this.txtOutMsg.Text = "";

            host.NameSpace = txtNameSpace.Text;
            host.SpaceName = txtModelpath.Text;
            host.ClassName = txtTableName.Text;
            host.DType = DbTypes.Sql;
            host.FileExtension = ".cs";

            host.ProviderName = server.ProviderName;
            host.ConnectionString = server.ConnectionString;

            int selectCount=0;
            foreach (var control in groupBox3.Controls)
            {
                if (control is CheckBox)
                {
                    if (((CheckBox)control).Checked)
                        selectCount++;
                }
            }

            if (selectCount < 1)
            {
                MessageBox.Show("请选择要生成的内容");
                return;
            }


            CodeTextDocument textPad = new CodeTextDocument(mainform);
            mainform.AddNewContent(textPad, TableName + " 代码");

            textPad.SelectedDatabaseType = ((ListItem)combTypes.Items[combTypes.SelectedIndex]).Value;

            backgroundWorker1.RunWorkerAsync(textPad);
            
        }

        private void btnCancle_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void CreateCodePicker_Load(object sender, EventArgs e)
        {
            this.btnApplyOk.Focus();
            mainform = (MainForm)Application.OpenForms["MainForm"];
            server = mainform.ConnectedDataBaseServer;

            this.panel1.BorderColor = mainform.XTheme.FormBorderOutterColor;

            listView1.PerformLayout();
            listView1.BeginUpdate();

            this.listView1.Columns.AddRange(new ColumnHeader[]{
               new ColumnHeader(){ Name ="名称", Text ="名称", Width =120 },
               new ColumnHeader(){ Name ="数据类型", Text ="数据类型", Width =140 },
               new ColumnHeader(){ Name ="标识", Text ="标识", Width =120 },
               new ColumnHeader(){ Name ="描述", Text ="描述", Width =100 }
            });

            using (var db = Utility.GetAdohelper(server))
            {
                DataTable table = db.GetTableObject(TableName);
                foreach (DataRow row in table.Rows)
                {
                    string columnName = row["ColumnName"] + "";
                    string typeName = row["TypeName"] + "";
                    string cisnull = row["CisNull"] + "";
                    string length = row["Length"] + "";
                    string describ = row["Describ"] + "";

                    cisnull = cisnull.Trim(',');

                    ListViewItem item = new ListViewItem(
                        new string[] { columnName, SnippetBase.getDataBaseDataType(typeName,length,server.ProviderName), cisnull, describ });
                    item.Text = columnName;
                    item.Name = columnName;

                    if (cisnull.Contains("pk"))
                    {
                        item.StateImageIndex = 0;
                        this.txtPKey.Text = columnName;
                    }
                    else
                    {
                        item.StateImageIndex = 1;
                    }

                    this.listView1.Items.Add(item);
                }
            }            

            listView1.EndUpdate();
            listView1.ResumeLayout();

        }

        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void txtOutMsg_TextChanged(object sender, EventArgs e)
        {

        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        private void groupBox3_Enter(object sender, EventArgs e)
        {

        }

        private void cbox_identity_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void progressBar1_Click(object sender, EventArgs e)
        {

        }

        private void label6_Click(object sender, EventArgs e)
        {

        }

        private void txtPKey_TextChanged(object sender, EventArgs e)
        {

        }

        private void label5_Click(object sender, EventArgs e)
        {

        }

        private void combTypes_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void txtModelpath_TextChanged(object sender, EventArgs e)
        {

        }

        private void label4_Click(object sender, EventArgs e)
        {

        }

        private void txtNameSpace_TextChanged(object sender, EventArgs e)
        {

        }

        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void label7_Click(object sender, EventArgs e)
        {

        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                if (e.Argument != null)
                {
                    CodeTextDocument textPad = e.Argument as CodeTextDocument;

                    using (var db = Utility.GetAdohelper(host.ConnectionString, host.ProviderName))
                    {
                        //host.Server = server;               
                        host.Table = db.GetTableObject(txtTableName.Text, NORM.DataBase.DataBaseSchema.Table);
                    }

                    string CodeText = string.Empty;

                    host.Pk_Column = new ColumnInfo();
                    host.Pk_Column.ColumnName = txtPKey.Text;

                    switch (textPad.SelectedDatabaseType)
                    {
                        case "Sql":
                            host.ToType = DbTypes.Sql;
                            host.Pk_Column.DefaultText = "@";
                            host.Pk_Column.TypeName = "Int";
                            host.Pk_Column.Length = "4";
                            host.Pk_Column.DefaultVal = "SqlDbType";
                            break;
                        case "MySql":
                            host.ToType = DbTypes.MySql;
                            host.Pk_Column.DefaultText = "@";
                            host.Pk_Column.TypeName = "Int32";
                            host.Pk_Column.Length = "4";
                            host.Pk_Column.DefaultVal = "MySqlDbType";
                            break;
                        case "Oracle":
                            host.ToType = DbTypes.Oracle;
                            host.Pk_Column.DefaultText = ":";
                            host.Pk_Column.TypeName = "Number";
                            host.Pk_Column.Length = "8";
                            host.Pk_Column.DefaultVal = "OracleType";
                            break;
                        case "OleDb":
                            host.ToType = DbTypes.OleDb;
                            host.Pk_Column.DefaultText = "@";
                            host.Pk_Column.TypeName = "Integer";
                            host.Pk_Column.Length = "4";
                            host.Pk_Column.DefaultVal = "OleDbType";
                            break;
                        case "SqlLite":
                            host.ToType = DbTypes.SqlLite;
                            host.Pk_Column.DefaultText = "@";
                            host.Pk_Column.TypeName = "Int32";
                            host.Pk_Column.Length = "4";
                            host.Pk_Column.DefaultVal = "DbType";
                            break;
                    }

                    this.Invoke(new MethodInvoker(() => { lblStateMsg.Text = "正在生成..."; }));

                    string Message = string.Empty;

                    if (checkModel.Checked)
                    {
                        if (checkNormEntity.Checked)
                        {
                            CodeText = CreateModel.CreateNormEntity(host, TableName, out Message);
                        }
                        else
                        {
                            CodeText = CreateModel.CreateNormModel(host, TableName, out Message);
                        }

                        this.Invoke(new MethodInvoker(() => { this.txtOutMsg.Text += Message; }));

                    }

                    this.Invoke(new MethodInvoker(() => { textPad.AddCodeTabPage(CodeText, "Model代码"); }));

                    backgroundWorker1.ReportProgress(1, 4);

                    CodeText = string.Empty;


                    if (checkIDAL.Checked)
                    {
                        if (checkNormEntity.Checked)
                        {
                            CodeText = CreateIDAL.CreateEntityIDAL(host, TableName, out Message);
                        }
                        else
                        {
                            CodeText = CreateIDAL.CreateModelDAL(host, TableName, out Message);
                        }

                        this.Invoke(new MethodInvoker(() => { this.txtOutMsg.Text += Message; }));

                    }


                    this.Invoke(new MethodInvoker(() => { textPad.AddCodeTabPage(CodeText, "IDAL代码"); }));
                    
                    backgroundWorker1.ReportProgress(2, 4);

                    CodeText = string.Empty;


                    if (checkDAL.Checked)
                    {
                        if (checkNormEntity.Checked)
                        {
                            CodeText = CreateDAL.CreateEntityDAL(host, TableName, out Message);
                        }
                        else
                        {
                            CodeText = CreateDAL.CreateModelDAL(host, TableName, out Message);
                        }

                        this.Invoke(new MethodInvoker(() => { this.txtOutMsg.Text += Message; }));

                    }


                    this.Invoke(new MethodInvoker(() => { textPad.AddCodeTabPage(CodeText, "DAL代码"); }));
                    
                    backgroundWorker1.ReportProgress(3, 4);

                    CodeText = string.Empty;


                    if (checkBLL.Checked)
                    {
                        if (checkNormEntity.Checked)
                        {
                            CodeText = CreateBLL.CreateEntityBLL(host, TableName, out Message);
                        }
                        else
                        {
                            CodeText = CreateBLL.CreateModelBLL(host, TableName, out Message);
                        }

                        this.Invoke(new MethodInvoker(() => { this.txtOutMsg.Text += Message; }));

                    }

                    this.Invoke(new MethodInvoker(() => { textPad.AddCodeTabPage(CodeText, "BLL代码"); }));
                    backgroundWorker1.ReportProgress(4, 4);

                    e.Result = true;
                }
                else
                {
                    e.Result = false;
                }
            }
            catch (Exception ex)
            {
                e.Result = false;
            }

        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Result != null)
            {
                lblStateMsg.Text = "生成完成";
                this.Close();
            }
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            int total = (int)e.UserState;
            int index = e.ProgressPercentage;
            double value = index * 1.0 / total * 100;
            this.progressBar1.Value = (int)value;
        }

        
    }
}
